# coding:utf-8

import cv2 as cv
import numpy as np


class HSVQuanMethod:
	Level72 = 1
	Level32 = 2


class HSVHistogram:
	def __init__(self, img, method, mask=None):
		self.hsvimg = cv.cvtColor(img, cv.COLOR_BGR2HSV)
		self.hist = []
		self.mask = mask
		if method == HSVQuanMethod.Level72:
			self.__method = self.__quanLevel72
			self.hist = np.zeros((72,))
		elif method == HSVQuanMethod.Level32:
			self.__method = self.__quanLevel32
			self.hist = np.zeros((32,))
		else:
			return
		self.__quantiztion()

	def __quantiztion(self):
		w = self.hsvimg.shape[1]
		h = self.hsvimg.shape[0]

		if self.mask is None:
			for x in xrange(0, w):
				for y in xrange(0, h):
					self.hist[self.__method(self.hsvimg[y, x, :])] += 1
		else:
			for x in xrange(0, w):
				for y in xrange(0, h):
					if self.mask[y, x] > 0:
						self.hist[self.__method(self.hsvimg[y, x, :])] += 1
		sum_count = sum(self.hist)
		for i in xrange(0, len(self.hist)):
			self.hist[i] = self.hist[i] / sum_count

	def __quanLevel72(self, pixel):
		h = pixel[0] * 2
		s = pixel[1] / 255.0
		v = pixel[2] / 255.0
		H = 0
		S = 0
		V = 0
		if (315.0 < h <= 360.0) or (0.0 <= h <= 20.0):
			H = 0
		elif 20.0 < h <= 40.0:
			H = 1
		elif 40.0 < h <= 75.0:
			H = 2
		elif 75.0 < h <= 155.0:
			H = 3
		elif 155.0 < h <= 190.0:
			H = 4
		elif 190.0 < h <= 270.0:
			H = 5
		elif 270.0 < h <= 295.0:
			H = 6
		elif 295.0 < h <= 315.0:
			H = 7

		if 0 <= s <= 0.2:
			S = 0
		elif 0.2 < s <= 0.7:
			S = 1
		elif 0.7 < s <= 1.0:
			S = 2

		if 0 <= v <= 0.2:
			V = 0
		elif 0.2 < v <= 0.7:
			V = 1
		elif 0.7 < v <= 1.0:
			V = 2
		return 3 * 3 * H + 3 * S + V

	def __quanLevel32(self, pixel):
		h = pixel[0] * 2
		s = pixel[1] / 255.0
		v = pixel[2] / 255.0
		H = 0
		S = 0
		V = 0
		if v <= 0.2:
			return 0

		if v > 0.2 and s <= 0.1:
			if v <= 0.5:
				return 1
			elif 0.5 < v <= 0.8:
				return 2
			elif 0.8 < v <= 1.0:
				return 3

		if (330.0 < h <= 360.0) or (0.0 <= h <= 20.0):
			H = 0
		elif 20.0 < h <= 45.0:
			H = 1
		elif 45.0 < h <= 75.0:
			H = 2
		elif 75.0 < h <= 165.0:
			H = 3
		elif 165.0 < h <= 200.0:
			H = 4
		elif 200.0 < h <= 270.0:
			H = 5
		elif 270.0 < h <= 330.0:
			H = 6

		if 0.1 < s <= 0.45:
			S = 0
		elif 0.45 < s <= 1:
			S = 1

		if 0.2 < v <= 0.55:
			V = 0
		elif 0.55 < v <= 1:
			V = 1
		return 4 + 2 * 2 * H + 2 * S + V
